#include <notifier.hpp>

JavaVM*      currentVM;
jmethodID    notifyMID;

#define CUBEFS_SOURCE "notifier.hpp:" CUBEFS_AT

void NotifyTypedObject(Typed* target, int signal) {
    if (target != NULL && target->GetPeer() != 0) {
        JNIEnv* env;
        currentVM->GetEnv((void**)&env, JNI_VERSION_1_4);

        if (target->GetPeerFlags() & WEAK_PEER)
        {
            jweak peer = (jweak)target->GetPeer();

            if (JNI_FALSE == env->IsSameObject(peer, NULL)) {
                env->CallBooleanMethod(peer, notifyMID, signal);
            }
            else {
                env->DeleteWeakGlobalRef(peer);
                target->SetPeer(0);
                target->SetPeerFlags(0);
            }
        }
        else {
            jobject peer = (jobject)target->GetPeer();
            env->CallBooleanMethod(peer, notifyMID, signal);
        }

        if (env->ExceptionCheck()) {
            env->ExceptionClear();
            throw CubefsException(CUBEFS_SOURCE, "Exception in java code in the event handler for object of type "+target->type()->name());
        }
    }
}


void CleanupPeer(Typed* target) {
    if (target != NULL && target->GetPeer() != 0) {
        JNIEnv* env;
        currentVM->GetEnv((void**)&env, JNI_VERSION_1_4);

        if (target->GetPeerFlags() & WEAK_PEER)
        {
            jweak peer = (jweak)target->GetPeer();
//            cout<<"Cleanup weak ref for object of type "<<target->type()->name()<<endl;
            env->DeleteWeakGlobalRef(peer);
        }
        else {
            jobject peer = (jobject)target->GetPeer();
//            cout<<"Cleanup global ref for object of type "<<target->type()->name()<<endl;
            env->DeleteGlobalRef(peer);
        }

        target->SetPeer(0);
        target->SetPeerFlags(0);
    }
}

#undef CUBEFS_SOURCE